<template>
  <el-container>
    <el-header class="no-flex" height="auto">
      <el-form
        label-width="70px"
        class="sys-filters"
        ref="formRef"
        inline
        :model="roleForm"
      >
        <el-form-item label="角色名称" prop="roleName">
          <el-input
            style="width: 200px"
            placeholder="请输入角色名称"
            clearable
            v-model="roleForm.roleName"
          />
        </el-form-item>

        <el-form-item label="角色编码" prop="rolePerm">
          <el-input
            style="width: 200px"
            placeholder="请输入角色编码"
            clearable
            v-model="roleForm.rolePerm"
          />
        </el-form-item>

        <el-form-item label="状态" prop="enabled">
          <el-select
            style="width: 200px"
            placeholder="请选择启动状态"
            clearable
            v-model="roleForm.enabled"
          >
            <el-option
              v-for="item in dicts.system_global_status"
              :key="item.v"
              :label="item.k"
              :value="item.v"
            />
          </el-select>
        </el-form-item>

        <el-form-item>
          <el-button type="primary" @click="roleSearch" icon="el-icon-search">
            搜索
          </el-button>
          <el-button @click="roleReset" icon="el-icon-refreshLeft">
            重置
          </el-button>
        </el-form-item>
        <el-form-item style="display: flex; margin-bottom: 0">
          <el-button type="primary" @click="add" icon="el-icon-plus" v-auths="['*:*:*','system:role:add']">新增</el-button>
          <el-button type="danger" icon="el-icon-delete"  v-auths="['*:*:*','system:role:delete']" >删除</el-button>
        </el-form-item>
      </el-form>
    </el-header>
    <el-main class="nopadding">
      <el-table
        :data="tableData"
        class="table"
        stripe
        border
      >
        <el-table-column align="center" type="selection"/>
        <el-table-column prop="roleName" label="角色名称" align="center"/>
        <el-table-column prop="rolePerm" label="权限字符" align="center"/>
        <el-table-column label="是否启用" align="center">
          <template #default="{row}">
            <template v-for="item in dicts.system_global_status">
              <el-tag v-if="row.enabled == item.v">{{item.k}}</el-tag>
            </template>
          </template>
        </el-table-column>
        <el-table-column prop="createTime" label="创建时间" :formatter="rendererDateTime" align="center"/>
        <el-table-column label="操作" align="center" width="180" fixed="right">
          <template #default="{ row }">
            <div class="sys-table-main-actions">
              <el-link
                icon="el-icon-edit"
                type="primary"
                :underline="false"
                @click="update(row.id)"
                v-auths="['*:*:*','system:role:update']"
              >
                修改
              </el-link>
              <el-link
                v-auths="['*:*:*','system:role:delete']"
                icon="el-icon-delete"
                type="danger"
                :underline="false"
                style="margin: 0 8px"
                @click="rowDelete(row.id)"
              >
                删除
              </el-link>
              <el-dropdown>
                <el-link
                  icon="el-icon-dArrowRight"
                  type="primary" :underline="false" style="margin-top: 6px;margin-left: 4px">
                  更多
                </el-link>
                <template #dropdown>
                  <el-dropdown-menu>
                    <el-dropdown-item  v-auths="['*:*:*','system:role:assigned']">
                      <router-link
                        :to="{
                              path:'/system/role/role-assign',
                              query:{ id: row.id }
                            }"
                        class="action-drop-item"
                      >
                        <span>分配用户</span>
                      </router-link>
                    </el-dropdown-item>
                  </el-dropdown-menu>
                </template>
              </el-dropdown>
            </div>
          </template>
        </el-table-column>
      </el-table>
    </el-main>
    <el-footer style="display: flex;justify-content: flex-end">
      <el-pagination
        :current-page="current"
        :page-size="size"
        :page-sizes="[10, 20, 50, 100]"
        layout="total, sizes, prev, pager, next, jumper"
        :total="total"
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
      />
    </el-footer>
    <el-dialog
      v-model="dialogFormVisible"
      :title="deForm.id ?'编辑角色':'新增角色'"
      width="600px"
      :append-to-body="true"
      :destroy-on-close="true"
      :before-close="onCancel"
    >
      <template #default>
        <el-form
          ref="formRef"
          :model="deForm"
          :rules="formRules"
          label-width="80px"

        >
          <el-form-item label="角色名称" prop="roleName">
            <el-input placeholder="请输入角色名称" v-model="deForm.roleName"/>
          </el-form-item>
          <el-form-item label="权限字符" prop="rolePerm">
            <el-input placeholder="请输入权限字符" v-model="deForm.rolePerm"/>
          </el-form-item>
          <el-form-item label="状态" prop="enabled">
            <el-radio-group v-model="deForm.enabled">
              <el-radio
                v-for="item in dicts.system_global_status"
                :key="item.v"
                :label="deForm.enabled==item.v?deForm.enabled:item.v "
              >
                {{ item.k }}
              </el-radio>
            </el-radio-group>
          </el-form-item>
          <el-form-item label="菜单权限">
            <div class="item-menu">
              <el-checkbox
                v-model="permission.openAll"
                @change="toggleTreeCollapse"
              >
                展开/折叠
              </el-checkbox>
              <el-checkbox
                v-model="permission.selectAll"
                @change="toggleTreeChecked"
              >
                全选/全不选
              </el-checkbox>
              <el-checkbox v-model="permission.linkage">
                父子(联动/不联动)
              </el-checkbox>

              <el-tree
                ref="menuTreeRef"
                :data="permission.treeList"
                :props="permission.treeProps"
                :check-strictly="!permission.linkage"
                :default-expand-all="permission.openAll"
                show-checkbox
                default-expand-all
                node-key="id"
                class="tree"
              />
            </div>
          </el-form-item>

          <el-form-item label="备注" prop="descript">
            <el-input
              type="textarea"
              placeholder="请输入内容"
              v-model="deForm.descript"
              :maxlength="200"
              show-word-limit
            />
          </el-form-item>
        </el-form>
      </template>

      <template #footer>
      <span class="dialog-footer">
        <el-button @click="onCancel">取消</el-button>
        <el-button type="primary" @click="onSubmit"> 确认 </el-button>
      </span>
      </template>
    </el-dialog>
  </el-container>
</template>

<script>
import {normalizeMenuList} from "./js";

export default {
  name: "index",
  dicts: ['system_global_status'],
  data() {
    return {
      ids: [], //批量选中
      roleForm: {
        roleName: "",
        rolePerm: "",
        enabled: '1',
      },
      dialogFormVisible: false,
      tableData: [],
      current: 1,
      size: 10,
      total: 10,
      deForm: {
        id: '',
        roleName: "",
        rolePerm: "",
        enabled: '1',
        descript: ""
      },
      formRules: {
        roleName: [
          {required: true, message: "请填写角色名称", trigger: "blur"}
        ],
        rolePerm: [
          {required: true, message: "请填写权限字符", trigger: "blur"}
        ]
      },
      permission: {
        openAll: false,
        selectAll: false,
        linkage: false,
        treeList: [],
        treeProps: {
          label: "name"
        }
      },
    }
  },
  created() {
    this.getRoleList()
  },
  methods: {
    async getRoleList() {
      let {data} = await this.$API.system.roles.list.get({
        current: this.current,
        size: this.size,
        roleName: this.roleForm.roleName,
        rolePerm: this.roleForm.rolePerm,
        enabled: this.roleForm.enabled
      })
      this.current = data.current
      this.total = data.total
      this.size = data.size
      this.roleForm = data.records
      this.tableData = data.records
    }, //角色列表
    roleSearch() {
      this.getRoleList()
    },
    roleReset() {
      this.$refs.formRef.resetFields()
      this.roleForm = {}
      this.getRoleList()
    },
    //单个删除
    rowDelete(id) {
      this.$confirm('此操作将删除此条数据,是否继续?', '提示', {
        confirmButtonText: '确定',
        cancelButtonClass: '取消',
        type: 'warning'
      }).then(async () => {
        await this.$API.system.roles.delete.get(id);
        this.$message({
          type: 'success',
          message: '删除成功'
        })
        this.getRoleList()
      })
    },
    //页码
    handleSizeChange(val) {
      this.size = val
      this.getRoleList()
    },
    handleCurrentChange(val) {
      this.current = val
      this.getRoleList()
    },
    // 选中的数组(批量删除..)
    handleSelectionChange(selection) {
      this.ids = selection.map(item => item.id)
    },
    // 转换时间
    rendererDateTime(row, column, cellValue, index) {
      return this.$TOOL.dateFormat(cellValue)
    },
    onCancel() {
      this.deForm = {} // 清空
      this.dialogFormVisible = false
      this.permission.openAll = false
      this.permission.selectAll = false
      this.permission.linkage = true
      this.toggleTreeChecked(false)
      this.toggleTreeCollapse(false)
    }, //关闭弹框
    add() {
      this.dialogFormVisible = true
      this.getMenuList()
    },
    async update(id) {
      let {data} = await this.$API.system.roles.detail.get(id)
      this.deForm.id = id
      this.deForm = data.role
      this.dialogFormVisible = true
      await this.$nextTick(()=>{
        this.$refs.menuTreeRef.setCheckedKeys(data.permissions)
      })
      this.getMenuList()
    },
    //菜单权限
    async getMenuList() {
      let {data} = await this.$API.system.menus.list.get({
        current:1,
        size:9999,
        enabled:1
      })
      this.permission.treeList = normalizeMenuList(data.records)
    },

    //提交
    async onSubmit(){
      const {id,roleName,rolePerm,enabled,descript } = this.deForm
      const { menuTreeRef } = this.$refs
      try {
        await this.$refs.formRef.validate()
        if (this.deForm.id) {
          //编辑
          await this.$API.system.roles.update.post({
            id,
            roleName,
            rolePerm,
            enabled,
            descript,
            permissionIds:[
              ...menuTreeRef.getCheckedKeys()
            ]
          })
        } else {
          // 新增
          await this.$API.system.roles.add.post({
            roleName,
            rolePerm,
            enabled,
            descript,
            permissionIds:[
              ...menuTreeRef.getCheckedKeys()
            ]
          })
        }
        this.deForm = {} //清空
        this.$message.success('操作成功')
        this.getRoleList()
        this.dialogFormVisible = false // 关闭弹窗
      } catch (error) {
        console.error(error)
        this.$message.error('操作失败')
      }
    },
    // 切换树形菜单的选中状态
    toggleTreeChecked(value) {
      const {menuTreeRef} = this.$refs
      // 如果权限联动开启，则将所有权限关联的菜单项都设置为选中状态
      this.permission.linkage ?
        this.permission.treeList.forEach(item => {
          menuTreeRef.setChecked(item, value, true)
        })
        // 如果权限联动关闭，则将所有菜单项的选中状态设置为value
        : menuTreeRef.setCheckedKeys(value ? this.resolveTreeListKeys() : [])
    },
    // 递归获取树形菜单的所有选中项的id
    resolveTreeListKeys(list) {
      list = list ?? this.permission.treeList
      return list
        .map(item => {
          return [
            item.id,
            ...(item.children ? this.resolveTreeListKeys(item.children) : [])
          ]
        })
        .flat()
    },
    // 切换树形菜单的展开状态
    toggleTreeCollapse(value) {
      const nodesMap = this.$refs.menuTreeRef.store.nodesMap
      // 将所有节点的展开状态设置为value
      Object.keys(nodesMap).forEach(key => (nodesMap[key].expanded = value))
    }

  }
}
</script>

<style scoped>
.item-menu {
  width: 100%;
}

.tree {
  margin-top: 0.5rem;
  background-color: #fff;
  border: 1px solid #dcdfe6;
  border-radius: 4px;
}
</style>
